#pragma once

#include "DXGIInterface.h"

namespace DX4WRT
{
	namespace DXGI
	{
		public ref class DXGI sealed
		{
			public:
				static IFactory2^ CreateFactory2 ();
				static IDevice2^ GetDeviceForObject (Platform::IntPtr obj);
		};

		ref class Factory : IFactory2
		{
			public:
				Factory (IDXGIFactory2 * pFactory);
				~Factory ();
				
				IAdapter^ EnumAdapters (uint32 adapter);
				IAdapter1^ EnumAdapters1 (uint32 Adapter);

				ISwapChain1^ CreateSwapChainForImmersiveWindow (IDevice^ device, Platform::Object^ window, SwapChainDescription1^ description, IOutput^ RestrictToOutput);

				property bool IsCurrent
				{
					bool get()
					{
						return m_pFactory->IsCurrent ();
					}
				}

				property bool IsWindowedStereoEnabled
				{
					bool get()
					{
						return m_pFactory->IsWindowedStereoEnabled ();
					};
				}

			private:
				IDXGIFactory2* m_pFactory;
		};

		ref class Adapter : IAdapter1
		{
			public:
				Adapter (IDXGIAdapter1* pAdapter);
				~Adapter ();

				void GetInternal (Platform::IntPtr* pVal);

				property Platform::String^ Description {Platform::String^ get();}
				property uint32 VendorId {uint32 get();}
				property uint32 DeviceId {uint32 get();}
				property uint32 SubSysId {uint32 get();}
				property uint32 Revision {uint32 get();}
				property uint64 DedicatedVideoMemory {uint64 get();}
				property uint64 DedicatedSystemMemory {uint64 get();}
				property uint64 SharedSystemMemory {uint64 get();}
				property AdapterOptions Flags {AdapterOptions get();}

			internal:
				IDXGIAdapter* GetNative ()
				{
					return m_pAdapter;
				}

			private:
				IDXGIAdapter1* m_pAdapter;
				DXGI_ADAPTER_DESC1* m_pDesc;

				void UpdateDescription ();
		};

		ref class Device : IDevice2
		{
			public:
				Device (IDXGIDevice2* pDevice);
				~Device ();

			internal:
				IDXGIDevice2* GetNative();

			private:
				IDXGIDevice2* m_pDevice;
		};

		ref class SwapChain : ISwapChain1
		{
			public:
				SwapChain (IDXGISwapChain1* pSwapChain);
				~SwapChain ();

				void Present (uint32 syncInterval, PresentOptions flags);
				void GetInternal (Platform::IntPtr* pVal);

				IDXGISwapChain1* GetNative() {return m_pSwapChain;}

			private:
				IDXGISwapChain1* m_pSwapChain;
		};
	}
}